/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.carpark.rest.client;

import cz.muni.fi.pa165.carpark.EmployeePosition;
import cz.muni.fi.pa165.carpark.TO.VehicleTO;
import cz.muni.fi.pa165.carpark.VehicleStatus;
import cz.muni.fi.pa165.carpark.rest.util.PropertyHelper;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.Before;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontValidate;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.UrlBinding;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

/**
 *
 * @author Ado
 */
@UrlBinding("/vehicle/{$event}/{vehicle.id}")
public class VehicleActionBean implements ActionBean {

    private ActionBeanContext context;
    private static final Logger log = LoggerFactory.getLogger(VehicleActionBean.class);
    
    @SpringBean
    private RestTemplate rt;
    
    @SpringBean
    private PropertyHelper ph;
    
    
    @ValidateNestedProperties(value = {
            @Validate(on = {"create", "save"}, field = "stateLicencePlate", required = true, maxlength= 10),
            @Validate(on = {"create", "save"}, field = "carProducer", required = true, minlength= 1),
            @Validate(on = {"create", "save"}, field = "carModel", required = true, minlength= 1),
            @Validate(on = {"create", "save"}, field = "yearOfManufacture", required = true, minvalue=1990),
            @Validate(on = {"create", "save"}, field = "engineType", required = true, maxlength= 10),
            @Validate(on = {"create", "save"}, field = "vin", required = true, minlength= 17, maxlength=17),
            @Validate(on = {"create", "save"}, field = "numberOfKms", required = true, minvalue=0),
            @Validate(on = {"create", "save"}, field = "availableForPositions", required = true),            
            @Validate(on = {"create", "save"}, field = "status", required = true)
            
    })
    private VehicleTO vehicle;  
    
    private boolean wasError = false;
    private String errorLicencePlate;
    
    @Validate(required=true, on="getByStatus")
    private VehicleStatus vehicleStatus;
    public VehicleStatus getVehicleStatus() {
        log.debug("Get status invoked ={}",this.vehicleStatus);
        return this.vehicleStatus;
    }
    
    public void setVehicleStatus(VehicleStatus vehicleStatus) {
        log.debug("Set status invoked={}",vehicleStatus);
        this.vehicleStatus = vehicleStatus;
    }
    
    public Resolution getByStatus(){
        log.debug("getBysTaus");
        return new ForwardResolution("/WEB-INF/jsp/vehicle.jsp");
    }
    
    @Validate(required=true, on="getByPosition")
    private EmployeePosition employeePosition;
    public EmployeePosition getEmployeePosition(){
        log.debug("get Employee postion ={}",this.employeePosition);
        return this.employeePosition;
    }
    
    public void setEmployeePosition(EmployeePosition employeePosition){
        log.debug("set employee position:{}",employeePosition);
        this.employeePosition = employeePosition;
    }
    
    public Resolution getByPosition(){
        log.debug("getByPosition({})",this.employeePosition);
        return new ForwardResolution("/WEB-INF/jsp/vehicle.jsp");
    }
    
    @DefaultHandler
    public Resolution all() {
        log.debug("Listing of all vehicles invoked");
        return new ForwardResolution("/WEB-INF/jsp/vehicle.jsp");
    }
    
    public boolean getWasError(){
        if(wasError){
            wasError = false;
            return true;
        }
        return false;
    }
    
    public String getErrorLicencePlate(){
        return errorLicencePlate;
    }
    
    public boolean getVehicleNoBiding(){
        if(vehicle==null){
            return false;
        }
        return true;
    }

    public Resolution add() {
        log.debug("add vehicle invoked");
        return new ForwardResolution("/WEB-INF/jsp/vehicleCreate.jsp");
    }

    public Resolution edit() {
        log.debug("edit() vehicle={}", vehicle);
        return new ForwardResolution("/WEB-INF/jsp/vehicleEdit.jsp");
    }

    public Resolution delete() {        
        log.debug("delete({})", vehicle.getId());
        String id = context.getRequest().getParameter("vehicle.id");
        if(id!=null){
            try{
                rt.delete( getURL("/{id}"),Long.parseLong(id));
            }catch(RestClientException ex){
                wasError = true;
                errorLicencePlate = vehicle.getStateLicencePlate();
            }
        }        
        return new ForwardResolution(this.getClass(), "all");
    }
    
    public Resolution details() {
        log.debug("details({})", vehicle.getId());
        return new ForwardResolution("/WEB-INF/jsp/vehicleDetails.jsp");
    }
    
    public Resolution serviceManagment(){
        log.debug("serviceManagment");
        this.vehicle = rt.getForObject(getURL("/{id}"), VehicleTO.class, vehicle.getId());
        log.debug("serviceManagment({})", this.vehicle.getId());
        log.debug(this.vehicle.toString());
        return new ForwardResolution("/WEB-INF/jsp/vehicleServicesManagment.jsp");
    }
    
    @Before(stages= LifecycleStage.BindingAndValidation, on= {"edit","save","details"})
    public void loadVehicle(){
        String id = context.getRequest().getParameter("vehicle.id");
        if(id == null){
            return;
        }
        this.vehicle = rt.getForObject(getURL("/{id}"), VehicleTO.class, Long.parseLong(id));
    }
    
    @DontValidate()
    public Resolution storno(){
        log.debug("storno create/edit vehicle");
        return new RedirectResolution(this.getClass(),"all");
    }

    public Resolution create() {
        log.debug("create vehicle={}", vehicle);
        rt.postForObject(getURL("/"), vehicle, VehicleTO.class);
        return new RedirectResolution(this.getClass(),"all");
    }

    public Resolution save() {
        log.debug("save() employee={}", vehicle);
        rt.put(getURL("/{id}"), vehicle, vehicle.getId());
        return new RedirectResolution(this.getClass(), "all");
    }

    @Override
    public ActionBeanContext getContext() {
        return context;
    }

    @Override
    public void setContext(ActionBeanContext context) {
        this.context = context;
    }

    public VehicleTO[] getVehicles() {
        log.debug("getAllVehicles");
        if(this.vehicleStatus == null && this.employeePosition == null){
            return rt.getForObject(getURL("/findall"), VehicleTO[].class);
        }
        else if(this.vehicleStatus != null){
            VehicleStatus tmp = this.vehicleStatus;
            this.vehicleStatus = null;
            return rt.getForObject(getURL("/findbystatus/{status}"), VehicleTO[].class, tmp);
        }
        else{
            EmployeePosition tmp = this.employeePosition;
            this.employeePosition = null;
            return rt.getForObject(getURL("/findbycategory/{category}"), VehicleTO[].class, tmp);
        }
    }
    
    public VehicleTO getVehicle() {
        return vehicle;
    }
    
    public void setVehicle(VehicleTO vehicle) {
        this.vehicle = vehicle;
    }
    
    private String getURL(String request) {
        return ph.getVehicleURL() + request + ph.getToken();
    }
    
}

